<script setup lang="tsx">
import { computed, ref, onMounted, watch } from 'vue';
import { NButton, NDivider, NPopconfirm, NTag, NCard, NSpace, NDescriptions, NDescriptionsItem, NSpin, NAlert, NGrid, NGi, NStatistic, NInput, NSelect, NPopover } from 'naive-ui';
import { useBoolean, useLoading } from '@sa/hooks';
import { jsonClone } from '@sa/utils';
import {
  fetchDeleteOutboundScript,
  fetchGetOutboundScriptList,
  fetchExportOutboundScript
} from '@/service/api/outbound';
import { useAppStore } from '@/store/modules/app';
import { useTable, useTableOperate } from '@/hooks/common/table';
import { useAuth } from '@/hooks/business/auth';
import { useDownload } from '@/hooks/business/download';
import ButtonIcon from '@/components/custom/button-icon.vue';
import { $t } from '@/locales';
import ScriptSearch from './modules/script-search.vue';
import ScriptOperateDrawer from './modules/script-operate-drawer.vue';
import TableHeaderOperation from '@/components/advanced/table-header-operation.vue';
import DataTable from '@/components/common/data-table.vue';

defineOptions({
  name: 'OutboundScriptList'
});

const { hasAuth } = useAuth();
const appStore = useAppStore();
const { download } = useDownload();
const { loading: exportLoading, startLoading: startExportLoading, endLoading: endExportLoading } = useLoading();

const wrapperRef = ref<HTMLElement>();

// 统计数据
const statistics = ref({
  totalScripts: 0,
  healthyScripts: 0,
  unhealthyScripts: 0,
  totalConcurrency: 0,
  avgConcurrency: 0
});

const {
  columns,
  columnChecks,
  data,
  getData,
  getDataByPage,
  loading,
  mobilePagination,
  searchParams,
  resetSearchParams
} = useTable({
  apiFn: fetchGetOutboundScriptList,
  apiParams: {
    pageNum: 1,
    pageSize: 10,
    scriptName: null,
    healthStatus: null,
    concurrency: null,
    params: {}
  },
  immediate: false,
  columns: () => [
    {
      type: 'selection',
      align: 'center',
      width: 48
    },
    {
      key: 'index',
      title: $t('common.index'),
      align: 'center',
      width: 64
    },
    {
      key: 'scriptName',
      title: '剧本名称',
      align: 'center',
      minWidth: 150,
      ellipsis: true
    },
    {
      key: 'healthStatus',
      title: '健康状态',
      align: 'center',
      width: 100,
      render: row => {
        const statusMap: Record<string, { label: string; type: 'default' | 'info' | 'success' | 'warning' | 'error' }> = {
          healthy: { label: '健康', type: 'success' },
          unhealthy: { label: '异常', type: 'error' }
        };
        const status = statusMap[row.healthStatus] || { label: '未知', type: 'default' };
        return <NTag type={status.type}>{status.label}</NTag>;
      }
    },
    {
      key: 'concurrency',
      title: '并发量',
      align: 'center',
      width: 100,
      render: row => {
        if (row.concurrency) {
          const level = row.concurrency <= 10 ? 'low' : row.concurrency <= 50 ? 'medium' : 'high';
          const colorMap = { low: '#18a058', medium: '#f0a020', high: '#d03050' };
          return <span style={`color: ${colorMap[level]}`}>{row.concurrency}</span>;
        }
        return '-';
      }
    },
    {
      key: 'description',
      title: '剧本描述',
      align: 'center',
      minWidth: 200,
      ellipsis: true
    },
    {
      key: 'createTime',
      title: '创建时间',
      align: 'center',
      width: 160,
      render: row => {
        if (row.createTime) {
          return new Date(row.createTime).toLocaleString();
        }
        return '-';
      }
    },
    {
      key: 'updateTime',
      title: '更新时间',
      align: 'center',
      width: 160,
      render: row => {
        if (row.updateTime) {
          return new Date(row.updateTime).toLocaleString();
        }
        return '-';
      }
    },
    {
      key: 'operate',
      title: $t('common.operate'),
      align: 'center',
      width: 200,
      render: row => {
        return (
          <div class="flex-center gap-8px">
            {hasAuth('outbound:script:edit') && (
              <NButton type="primary" ghost size="small" onClick={() => edit(row.scriptId)}>
                编辑
              </NButton>
            )}
            {hasAuth('outbound:script:delete') && (
              <NPopconfirm onPositiveClick={() => handleDelete([row.scriptId])}>
                {{
                  trigger: () => (
                    <NButton type="error" ghost size="small">
                      删除
                    </NButton>
                  ),
                  default: () => '确定要删除这个剧本吗？'
                }}
              </NPopconfirm>
            )}
            {hasAuth('outbound:script:view') && (
              <NButton type="info" ghost size="small" onClick={() => handleViewDetail(row)}>
                查看
              </NButton>
            )}
          </div>
        );
      }
    }
  ]
});

const {
  drawerVisible,
  operateType,
  editingData,
  handleAdd,
  handleEdit,
  checkedRowKeys,
  onBatchDeleted,
  onDeleted
} = useTableOperate(data, getData);

// 计算统计数据
function calculateStatistics() {
  if (!data.value || data.value.length === 0) {
    statistics.value = {
      totalScripts: 0,
      healthyScripts: 0,
      unhealthyScripts: 0,
      totalConcurrency: 0,
      avgConcurrency: 0
    };
    return;
  }

  const total = data.value.length;
  const healthy = data.value.filter(item => item.healthStatus === 'healthy').length;
  const unhealthy = data.value.filter(item => item.healthStatus === 'unhealthy').length;
  const totalConcurrency = data.value.reduce((sum, item) => sum + (item.concurrency || 0), 0);
  const avgConcurrency = total > 0 ? Math.round(totalConcurrency / total) : 0;

  statistics.value = {
    totalScripts: total,
    healthyScripts: healthy,
    unhealthyScripts: unhealthy,
    totalConcurrency,
    avgConcurrency
  };
}

async function handleBatchDelete() {
  // request
  await fetchDeleteOutboundScript(checkedRowKeys.value);

  onBatchDeleted();
}

async function handleDelete(scriptIds: CommonType.IdType[]) {
  try {
    await fetchDeleteOutboundScript(scriptIds);
    window.$message?.success('删除成功');
    getData();
  } catch (error) {
    console.error('删除失败:', error);
    window.$message?.error('删除失败');
  }
}

function edit(id: CommonType.IdType) {
  handleEdit(id);
}

function handleViewDetail(row: any) {
  // 查看详情逻辑
  console.log('查看详情:', row);
}

async function handleExport() {
  startExportLoading();
  try {
    await download(() => fetchExportOutboundScript(searchParams), '外呼剧本列表.xlsx');
  } finally {
    endExportLoading();
  }
}

// 监听数据变化，重新计算统计
onMounted(() => {
  getData();
});

// 数据加载完成后计算统计
watch(data, () => {
  calculateStatistics();
}, { immediate: true });
</script>

<template>
  <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
    <ScriptSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />

    <NCard title="外呼剧本管理" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
      <template #header-extra>
        <TableHeaderOperation
          v-model:columns="columnChecks"
          :disabled-delete="checkedRowKeys.length === 0"
          :loading="loading"
          :show-add="hasAuth('outbound:script:add')"
          :show-delete="hasAuth('outbound:script:remove')"
          :show-export="hasAuth('outbound:script:export')"
          @add="handleAdd"
          @delete="handleBatchDelete"
          @export="handleExport"
          @refresh="getData"
        />
      </template>

      <DataTable
        v-model:checked-row-keys="checkedRowKeys"
        :columns="columns"
        :data="data"
        size="small"
        :flex-height="!appStore.isMobile"
        :scroll-x="1200"
        :loading="loading"
        remote
        :row-key="row => row.scriptId"
        :pagination="mobilePagination"
        class="sm:h-full"
      />

      <ScriptOperateDrawer
        v-model:visible="drawerVisible"
        :operate-type="operateType"
        :row-data="editingData"
        @submitted="getDataByPage"
      />
    </NCard>
  </div>
</template>

<style scoped>
.card-wrapper {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  transition: all 0.3s ease;
}

.card-wrapper:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.stat-card {
  text-align: center;
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (max-width: 768px) {
  .stat-card {
    min-height: 100px;
  }
}

@media (max-width: 480px) {
  .stat-card {
    min-height: 80px;
  }
}
</style>
